package com.ivo.core.hibernate;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.ivo.sec.SessionLocal;
import com.ivo.util.DateUtil;
import com.ivo.util.ReflectionUtil;

/**
 * 模型对象操作类, 继承自实体对象操作类
 *
 * @param <T> 具体模型类型，<a>Model</a>的子类
 * @author nexf
 */
public abstract class ModelManager<T extends Model> {

  protected Logger logger = LoggerFactory.getLogger(this.getClass());

  /**
   * 泛型所指定的Class 类型，用于hibernate 查询时使用
   */
  protected Class<T> entityClass;

  /**
   * hibernate代理工具
   */
  @Autowired
  protected HibernateInvoker hibernateInvoker;
  
  @SuppressWarnings("unchecked")
  public ModelManager() {
    this.entityClass = (Class<T>) ReflectionUtil.getSuperClassGenericType(getClass());
  }

  /**
   * 验证主键的合法性
   *
   * @param id 待验证对象唯一标识符
   * @return boolean true or false
   */
  public boolean validate(final String id) {
    return id != null && !id.trim().equals("");
  }

  /**
   * 保存时以当前时间为更新时间，如果创建时间为null，则以当前时间为创建时间
   *
   * @param entity 待保存对象
   */
  private void preSave(final T entity) {
    if (entity == null) {
      return;
    }
    Date date = DateUtil.getNow();
    if (entity.getCreateTime() == null) {
      entity.setCreateTime(date);
    }
    entity.setUpdateTime(date);

    String identityId="sys";
    if(SessionLocal.getUser()!=null)
    	identityId = SessionLocal.getUser().getUser_id();
    if (entity.getCreator() == null) {
      entity.setCreator(identityId);
    }
    entity.setUpdater(identityId);
  }

  /**
   * 保存
   *
   * @param entity 待保存对象
   */
  public void save(final T entity) { 
    preSave(entity);
    hibernateInvoker.save(entity);
  }

  /**
   * 删除
   *
   * @param id 待删除对象唯一标识符
   */
  public int delete(final String id) {
    return delete(new String[]{id});
  }

  /**
   * 批量删除
   *
   * @param ids 待删除对象唯一标识符
   */
  public int delete(final String[] ids) {
    if (ids == null || ids.length == 0) {
      return 0;
    }
    String identityId="sys";
    if(SessionLocal.getUser()!=null)
    	identityId = SessionLocal.getUser().getUser_id();
    String hql = "update " + entityClass.getName() + " x set x.isValid = false,"
        + " updater = ?0, updateTime = CURRENT_TIME() where x.isValid is true and x.id in ?1";
    return hibernateInvoker.bulkUpdate(hql, identityId, Arrays.asList(ids));
  }

	/**
	 * 删除
	 * 
	 * @param id 待删除对象唯一标识符
	 */
	public int delete(final Long id) {
		return delete(new Long[]{id});
	}
	
	/**
	 * 批量删除
	 * 
	 * @param ids 待删除对象唯一标识符
	 * @return 
	 */
	public int delete(final Long[] ids) {
	    if (ids == null || ids.length == 0) {
	        return 0;
	      }
	      String identityId="sys";
	      if(SessionLocal.getUser()!=null)
	    	  identityId = SessionLocal.getUser().getUser_id();
	      String hql = "update " + entityClass.getName() + " x set x.isValid = false,"
	          + " updater = ?0, updateTime = CURRENT_TIME() where x.isValid is true and x.id in ?1";
	      return hibernateInvoker.bulkUpdate(hql, identityId, Arrays.asList(ids));
	}
  
  /**
   * 获取实体对象实例
   *
   * @param id 要查找对象的唯一标识符
   * @return T 实体对象实例， 找不到时返回null
   */
  public T get(final String id) {
    if (validate(id)) {
      return hibernateInvoker.get(entityClass, id);
    }
    return null;
  }

  /**
   * 获取唯一对象, 结果不唯一时取第结果集一条记录作为返回结果
   *
   * @param queryString 待执行查询语句
   * @param values 参数列表
   * @return T 查询结果
   */
  public T findUnique(String queryString, Object... values) {
    return hibernateInvoker.findUnique(entityClass, queryString, values);
  }

  /**
   * 进行查询
   *
   * @param queryString 待执行查询语句
   * @param values 参数列表
   * @return List<T> 查询结果
   */
  public List<T> find(String queryString, Object... values) {
    return hibernateInvoker.find(entityClass, queryString, values);
  }

  /**
   * 指定条件查询，返回limit个对象
   *
   * @param limit 返回结果数量
   * @param queryString 待执行查询语句
   * @param values 参数列表
   * @return List<T> 查询结果
   */
  public List<T> find(int limit, String queryString, Object... values) {
    return hibernateInvoker.find(entityClass, limit, queryString, values);
  }

  /**
   * 分页查询
   *
   * @param pno 待查询页码
   * @param psize 分页大小
   * @param queryString 待执行查询语句
   * @param values 参数列表
   * @return List<T> 查询结果
   */
  public List<T> find(int pno, int psize, String queryString, Object... values) {
    return hibernateInvoker.find(entityClass, pno, psize, queryString, values);
  }

  /**
   * 计算语句执行结果的条目数量
   *
   * @param queryString 待执行查询语句
   * @param values 参数列表
   * @return Long 统计数量
   */
  public Long count(final String queryString, final Object... values) {
    return hibernateInvoker.count(queryString, values);
  }

}
